package zgrjb.snbq.teach_platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zgrjb.snbq.teach_platform.dto.model.NotificationDO;
import zgrjb.snbq.teach_platform.mapper.NotificationMapper;
import zgrjb.snbq.teach_platform.service.NotificationService;
import zgrjb.snbq.teach_platform.util.IDUtil;
import zgrjb.snbq.teach_platform.util.JsonData;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 通知服务实现类
 * 
 * @author system
 * @since 2024-12-28
 */
@Slf4j
@Service
public class NotificationServiceImpl implements NotificationService {

    @Autowired
    private NotificationMapper notificationMapper;

    @Override
    @Transactional
    public JsonData createSystemNotification(Long userId, String title, String content, Integer priority) {
        try {
            NotificationDO notification = NotificationDO.builder()
                .id((Long) IDUtil.geneSnowFlakeID())
                .userId(userId)
                .type("system")
                .title(title)
                .content(content)
                .priority(priority != null ? priority : 1)
                .isRead(0)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

            notificationMapper.insert(notification);

            log.info("创建系统通知成功，通知ID: {}", notification.getId());
            return JsonData.buildSuccess(notification);

        } catch (Exception e) {
            log.error("创建系统通知失败", e);
            return JsonData.buildError("创建通知失败");
        }
    }

    @Override
    @Transactional
    public JsonData createTaskNotification(Long userId, String title, String content, 
                                         Long sourceId, String sourceType) {
        try {
            NotificationDO notification = NotificationDO.builder()
                .id((Long) IDUtil.geneSnowFlakeID())
                .userId(userId)
                .type("task")
                .title(title)
                .content(content)
                .priority(2) // 任务通知默认中等优先级
                .sourceId(sourceId)
                .sourceType(sourceType)
                .isRead(0)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

            notificationMapper.insert(notification);

            log.info("创建任务通知成功，通知ID: {}", notification.getId());
            return JsonData.buildSuccess(notification);

        } catch (Exception e) {
            log.error("创建任务通知失败", e);
            return JsonData.buildError("创建通知失败");
        }
    }

    @Override
    public JsonData getUserNotifications(Long userId, int page, int size, String type) {
        try {
            Page<NotificationDO> pageParam = new Page<>(page, size);
            QueryWrapper<NotificationDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            
            if (type != null && !type.isEmpty()) {
                wrapper.eq("type", type);
            }
            
            wrapper.orderByDesc("priority", "create_time");

            IPage<NotificationDO> result = notificationMapper.selectPage(pageParam, wrapper);

            Map<String, Object> data = new HashMap<>();
            data.put("list", result.getRecords());
            data.put("total", result.getTotal());
            data.put("current", result.getCurrent());
            data.put("size", result.getSize());

            return JsonData.buildSuccess(data);

        } catch (Exception e) {
            log.error("获取用户通知失败", e);
            return JsonData.buildError("获取通知失败");
        }
    }

    @Override
    @Transactional
    public JsonData markNotificationAsRead(Long notificationId, Long userId) {
        try {
            NotificationDO notification = notificationMapper.selectById(notificationId);
            if (notification == null || !notification.getUserId().equals(userId)) {
                return JsonData.buildError("通知不存在或无权限");
            }

            notification.setIsRead(1);
            notification.setUpdateTime(LocalDateTime.now());
            notificationMapper.updateById(notification);

            return JsonData.buildSuccess("标记已读成功");

        } catch (Exception e) {
            log.error("标记通知已读失败", e);
            return JsonData.buildError("标记已读失败");
        }
    }

    @Override
    @Transactional
    public JsonData markAllAsRead(Long userId) {
        try {
            QueryWrapper<NotificationDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId).eq("is_read", 0);

            NotificationDO updateNotification = new NotificationDO();
            updateNotification.setIsRead(1);
            updateNotification.setUpdateTime(LocalDateTime.now());

            int updated = notificationMapper.update(updateNotification, wrapper);
            
            return JsonData.buildSuccess("已标记 " + updated + " 条通知为已读");

        } catch (Exception e) {
            log.error("批量标记已读失败", e);
            return JsonData.buildError("批量标记已读失败");
        }
    }

    @Override
    public JsonData getUnreadNotificationCount(Long userId) {
        try {
            QueryWrapper<NotificationDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId).eq("is_read", 0);

            Long count = notificationMapper.selectCount(wrapper);
            return JsonData.buildSuccess(count);

        } catch (Exception e) {
            log.error("获取未读通知数量失败", e);
            return JsonData.buildError("获取未读数量失败");
        }
    }

    @Override
    @Transactional
    public JsonData deleteNotification(Long notificationId, Long userId) {
        try {
            NotificationDO notification = notificationMapper.selectById(notificationId);
            if (notification == null || !notification.getUserId().equals(userId)) {
                return JsonData.buildError("通知不存在或无权限");
            }

            notificationMapper.deleteById(notificationId);
            return JsonData.buildSuccess("删除通知成功");

        } catch (Exception e) {
            log.error("删除通知失败", e);
            return JsonData.buildError("删除通知失败");
        }
    }

    @Override
    public JsonData generateAISuggestion(Long notificationId) {
        try {
            NotificationDO notification = notificationMapper.selectById(notificationId);
            if (notification == null) {
                return JsonData.buildError("通知不存在");
            }

            // 根据通知类型生成AI建议
            String aiSuggestion = generateSuggestionByType(notification);
            
            notification.setAiSuggestion(aiSuggestion);
            notification.setUpdateTime(LocalDateTime.now());
            notificationMapper.updateById(notification);

            return JsonData.buildSuccess(aiSuggestion);

        } catch (Exception e) {
            log.error("生成AI建议失败", e);
            return JsonData.buildError("生成AI建议失败");
        }
    }

    /**
     * 根据通知类型生成AI建议
     */
    private String generateSuggestionByType(NotificationDO notification) {
        String type = notification.getType();
        String content = notification.getContent();

        switch (type) {
            case "task":
                return "建议：1. 及时查看任务详情 2. 合理安排时间完成 3. 如有疑问可联系相关老师";
            case "exam":
                return "建议：1. 提前准备考试资料 2. 复习相关知识点 3. 注意考试时间和地点";
            case "assignment":
                return "建议：1. 仔细阅读作业要求 2. 按时提交避免扣分 3. 保证作业质量";
            case "system":
                if (content.contains("升级") || content.contains("维护")) {
                    return "建议：1. 提前保存工作进度 2. 关注系统恢复时间 3. 避免在维护期间进行重要操作";
                } else {
                    return "建议：1. 及时关注系统公告 2. 了解新功能使用方法 3. 如有问题可联系技术支持";
                }
            case "approval":
                return "建议：1. 及时处理审批请求 2. 仔细审查申请内容 3. 给出明确的审批意见";
            default:
                return "建议：请及时查看通知内容并采取相应行动";
        }
    }
} 